//
//  SDImage.m
//  SKinDiary
//
//  Created by pcyang on 16/6/26.
//  Copyright © 2016年 tencent. All rights reserved.
//

#import "SDImage.h"
#import "SDImageCacheEx.h"

#define Image_DefaultBundleName @"Default"//默认资源库
#define Image_ResBundleName @"Default"//当前资源库
#define Image_BundlePrefix @""//资源库前缀

@implementation SDImage

@end

@implementation UIImage(SDOperation)
+ (UIImage*)imageNamedWithoutCache:(NSString*)imageName
{
    NSArray *imageNameArr = [imageName componentsSeparatedByString:@"."];
    NSString*fileName = nil;
    NSString*extension = nil;
    
    @try {
        fileName = [imageNameArr objectAtIndex:0];
        extension = [imageNameArr objectAtIndex:1];
    }
    @catch (NSException *exception) {}
    
    NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
    return [UIImage imageWithContentsOfFile:fileLocation];
}

- (CGBitmapInfo)decodedBitmapInfoWithColorSpace:(CGColorSpaceRef)colorSpace
{
    CGImageRef imageRef = self.CGImage;
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    
    int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);
    BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone ||
                        infoMask == kCGImageAlphaNoneSkipFirst ||
                        infoMask == kCGImageAlphaNoneSkipLast);
    
    // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.
    // https://developer.apple.com/library/mac/#qa/qa1037/_index.html
    if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1)
    {
        // Unset the old alpha info.
        bitmapInfo &= ~kCGBitmapAlphaInfoMask;
        
        // Set noneSkipFirst.
        bitmapInfo |= kCGImageAlphaNoneSkipFirst;
    }
    // Some PNGs tell us they have alpha but only 3 components. Odd.
    else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3)
    {
        // Unset the old alpha info.
        bitmapInfo &= ~kCGBitmapAlphaInfoMask;
        bitmapInfo |= kCGImageAlphaPremultipliedFirst;
    }
    
    return bitmapInfo;
}

- (UIImage*)decodedImage
{
    CGImageRef imageRef = self.CGImage;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
    CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize};
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 (int)imageSize.width,
                                                 (int)imageSize.height,
                                                 CGImageGetBitsPerComponent(imageRef),
                                                 0,
                                                 colorSpace,
                                                 [self decodedBitmapInfoWithColorSpace:colorSpace]);
    CGColorSpaceRelease(colorSpace);
    
    // If failed, return undecompressed image
    if (!context) return self;
    
    CGContextDrawImage(context, imageRect, imageRef);
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
    
    CGContextRelease(context);
    
    UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:[[UIScreen mainScreen] scale] orientation:self.imageOrientation];
    CGImageRelease(decompressedImageRef);
    return decompressedImage;
}


- (UIImage*)imageOriginRect:(CGRect)cutRect scaled:(CGFloat)scaled rotated:(CGFloat)angle
{
    UIGraphicsBeginImageContext(CGSizeMake(cutRect.size.width*scaled, cutRect.size.height*scaled));
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextRotateCTM(context,angle);
    
    CGSize imageSize = self.size;
    [self drawInRect:CGRectMake(-cutRect.origin.x*scaled, -cutRect.origin.y*scaled, imageSize.width*scaled, imageSize.height*scaled)];
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return imageCopy;
}

- (UIImage*)imageOriginRect:(CGRect)cutRect newSize:(CGSize)newSize
{
    CGFloat scaleX = newSize.width/cutRect.size.width;
    CGFloat scaleY = newSize.height/cutRect.size.height;
    CGFloat scale = MIN(scaleX, scaleY);
    scale = MIN(scale, 1.0);
    
    return [self imageOriginRect:cutRect scaled:scale rotated:0.0];
}

- (UIImage*)imageWithNewHeight:(CGFloat)height
{
    CGFloat scale = height/self.size.height;
    if( scale > 1.0 )return self;
    
    return [self imageOriginRect:CGRectMake(0, 0, self.size.width, self.size.height) scaled:scale rotated:0.0];
}


- (UIImage*)imageWithNewWidth:(CGFloat)width
{
    CGFloat scale = width/self.size.width;
    if( scale > 1.0 )return self;
    
    return [self imageOriginRect:CGRectMake(0, 0, self.size.width, self.size.height) scaled:scale rotated:0.0];
}

+ (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect frame = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, frame);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}

- (UIImage*)subImageWithRect:(CGRect)rect
{
    return [self imageOriginRect:rect newSize:rect.size];
}

+ (UIImage*)imageFromView:(CALayer*)layer
{
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, NO, 0);
    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

- (UIImage *)resizableImageWithCapInsetsEx:(UIEdgeInsets)capInsets {
    if ([self respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)]) {
        return [self resizableImageWithCapInsets:capInsets resizingMode:UIImageResizingModeStretch];
    }
    //    else if ([self respondsToSelector:@selector(resizableImageWithCapInsets:)]) {
    //        return [self resizableImageWithCapInsets:capInsets];
    //    }
    else {
        return [self stretchableImageWithLeftCapWidth:MAX(capInsets.left, capInsets.right) topCapHeight:MAX(capInsets.top, capInsets.bottom)];
    }
}

+ (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize
{
    UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
    [image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
    UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return reSizeImage;
    
}
-(UIImage*) stretchNineImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight
{
    if([self respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)])
    {
        UIEdgeInsets inserts;
        inserts.top = topCapHeight;
        inserts.left = leftCapWidth;
        inserts.right = self.size.width-1;
        inserts.bottom = self.size.height-1;
        return [self resizableImageWithCapInsets:inserts resizingMode:UIImageResizingModeStretch];
    }
    //    else if([self respondsToSelector:@selector(resizableImageWithCapInsets:)])
    //    {
    //        UIEdgeInsets inserts;
    //        inserts.top = topCapHeight;
    //        inserts.left = leftCapWidth;
    //        inserts.right = self.size.width-1;
    //        inserts.bottom = self.size.height-1;
    //        return [self resizableImageWithCapInsets:inserts];
    //    }
    else if([self respondsToSelector:@selector(stretchableImageWithLeftCapWidth:topCapHeight:)])
    {
        return   [self  stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];
    }
    
    
    
    return nil;
}

- (void)drawInRectOptimized:(CGRect)rect
{
    CGSize size = self.size;
    CGFloat scaleX = rect.size.width/size.width;
    CGFloat scaleY = rect.size.height/size.height;
    CGFloat scale = MIN(scaleX, scaleY);
    //        scale = MIN(scale, 1.0);
    CGSize newsize = CGSizeMake(size.width*scale, size.height*scale);
    [self drawInRect:CGRectMake(rect.origin.x+(rect.size.width-newsize.width)/2, rect.origin.y+(rect.size.height-newsize.height)/2, newsize.width, newsize.height)];
}
@end

@implementation UIImage (SELF_DEFINED)
+ (UIImage*)staticImageWithName:(NSString*)name
{
    if( name == nil )return nil;
    NSString* other = [name stringByDeletingPathExtension];
    NSString* extension = [name pathExtension];
    NSRange range = [other rangeOfString:@"@2x"];
    if( range.location == NSNotFound )
    {
        name = [NSString stringWithFormat:@"%@@2x.%@",other,extension];
    }
    
    return [[SDImageCacheEx sharedInstance]getImageWithNameInMainBundle:name];
}
+ (UIImage*)staticImageWithPath:(NSString*)path
{
    if( path == nil )return nil;
    return [[SDImageCacheEx sharedInstance] getImageWithPath:path];
}


UIImage* SDGetImageByName(NSString* imageName)
{
    UIImage *image = nil;
    NSString *phone4Suffix = @"";
    if ([UIScreen mainScreen].bounds.size.height==480) {
        phone4Suffix=@"_to4";
    }else{
        phone4Suffix=@"";
    }
    NSString *fullImageName=[NSString stringWithFormat:@"%@%@%@@%dx",@"",imageName,phone4Suffix,(int)[UIScreen mainScreen].scale];
    
    NSString *defaultPath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.bundle",Image_DefaultBundleName]];
    NSString *resourcePath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.bundle",Image_ResBundleName]];
    
    NSBundle *defaultBundle=[NSBundle bundleWithPath:defaultPath];
    NSBundle *resourceBundle=[NSBundle bundleWithPath:resourcePath];
    
    NSString *imagePath=[resourceBundle pathForResource:fullImageName ofType:@"png"];
    if (!imagePath)
    {
        imagePath=[defaultBundle pathForResource:imageName ofType:@"jpg"];
    }
    
    if (!imagePath) {
        imagePath=[resourceBundle pathForResource:fullImageName ofType:@"jpg"];
    }
    if (!imagePath) {
        imagePath=[defaultBundle pathForResource:fullImageName ofType:@"png"];
    }
    if (!imagePath) {
        imagePath=[defaultBundle pathForResource:fullImageName ofType:@"jpg"];
    }
    if (!imagePath)
    {
        fullImageName=[NSString stringWithFormat:@"%@%@@%dx",@"",imageName,(int)[UIScreen mainScreen].scale];
        imagePath=[resourceBundle pathForResource:fullImageName ofType:@"png"];
        if (!imagePath) {
            imagePath=[resourceBundle pathForResource:fullImageName ofType:@"jpg"];
        }
        if (!imagePath) {
            imagePath=[defaultBundle pathForResource:fullImageName ofType:@"png"];
        }
        if (!imagePath) {
            imagePath=[defaultBundle pathForResource:fullImageName ofType:@"jpg"];
        }
    }
    if (imagePath)
    {
        image=[UIImage staticImageWithPath:imagePath];
    }
    else
    {
        imagePath = [NSString stringWithFormat:@"Default.bundle/%@", imageName];
        if (imagePath)
            image = [UIImage imageNamed:imagePath];
    }
    
    return image;
}


+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size {
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]);
    } else {
        UIGraphicsBeginImageContext(size);
    }
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

+ (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height
{
    CGFloat oldWidth = image.size.width;
    CGFloat oldHeight = image.size.height;
    
    CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
//    CGFloat scaleFactor = width / oldWidth;
  
    CGFloat newHeight = oldHeight * scaleFactor;
    CGFloat newWidth = oldWidth * scaleFactor;
    CGSize newSize = CGSizeMake(newWidth, newHeight);
    
//    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
//    [image drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
//    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//    UIGraphicsEndImageContext();
//    
//    //return newImage;
    return [self imageWithImage:image scaledToSize:newSize];
}

+(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width
{
    float oldWidth = sourceImage.size.width;
    float oldHeight = sourceImage.size.height;

    float scaleFactor = i_width / oldWidth;
    
    float newHeight = sourceImage.size.height * scaleFactor;
    float newWidth = oldWidth * scaleFactor;
    
    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
    [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

- (UIImage *)drawImage:(UIImage *)inputImage inRect:(CGRect)frame {
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0);
    [self drawInRect:CGRectMake(0.0, 0.0, self.size.width, self.size.height)];
    [inputImage drawInRect:frame];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
@end
